package com.jjh.interceptor;

import com.jjh.annation.UnToken;
import com.jjh.consts.Key;
import com.jjh.consts.ResEnum;
import com.jjh.exception.TokenException;
import com.jjh.utils.JwtUtil;
import com.jjh.utils.RedisUtils;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import java.lang.reflect.Method;
import java.util.Date;

/**
 * token校验拦截器
 */
@Component
public class TokenInterceptor implements HandlerInterceptor {

    @Autowired
    private RedisUtils redisUtils;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //预检查直接放行
        if(request.getMethod().equals("OPTIONS")){
            return true;
        }
        if (handler instanceof HandlerMethod handlerMethod) {
            Method method = handlerMethod.getMethod();
            // 检查方法上是否有@UnToken注解
            if (method.isAnnotationPresent(UnToken.class)) {
                return true; // 直接放行
            }
        }

        // System.out.println("---------------");
        String token = request.getHeader("token");
        if(ObjectUtils.isEmpty(token)||"".equals(token)){
            throw new TokenException(ResEnum.TOKEN_NULL_ERROR,"token为空！");
        }
//
//        //获取threadLocal中的用户
//       // User user = UserThreadLocal.get();
//        redisUtils.getString("")
//        if(ObjectUtils.isEmpty(user)){
//            //用户为空，说明还没登录，拦截
//             throw new UnAuthenticationException(ResEnum.UN_AUTHENTICATION_ERROR,"未认证！");
//        }

        //解析token
        JwtUtil jwtUtil = new JwtUtil();
        //判断token是否过期
        if(jwtUtil.isExpiration(token)){
            //过期，返回过期错误
            throw new TokenException(ResEnum.TOKEN_EXPIRATION_ERROR,"token过期");
        }


        //没过期，可以进行解析和比对了
        String userid = jwtUtil.parseToken(token);
        //从redis中获取用户信息
        String userinfo = redisUtils.getString(Key.USER + userid);

        if(userinfo == null || "".equals(userinfo)){
            throw new TokenException(ResEnum.TOKEN_ERROR,"token错误!");
        }
        //token都没错，检查一下是否小于三分钟
        Date expirationDate = jwtUtil.getExpirationDate(token);
        int expirationMius = (int) (expirationDate.getTime() - System.currentTimeMillis() / (1000*60));
        if(expirationMius > 0 && expirationMius < 3){
            //小于三分钟了则需要跟新
            String newToken = jwtUtil.refreshToken(token);
            //将token写回去,这里模拟一个异常，利用异常处理器歇会去
            throw new TokenException(ResEnum.TOKEN_REFRESH,newToken);
        }
        //最终放行
        return true;

    }
}
